/*******************************************************************************
 * Copyright (c) 2011 LegSem.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl-3.0.txt
 * 
 * Contributors:
 *     LegSem - initial API and implementation
 ******************************************************************************/
package com.legsem.legstar.cci;

import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.cci.ConnectionMetaData;
import javax.resource.cci.Interaction;
import javax.resource.cci.LocalTransaction;
import javax.resource.cci.ResultSetInfo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.legsem.legstar.jca.LegStarManagedConnection;

/**
 * Generic, transport agnostic, CCI connection.
 * 
 */
public abstract class LegStarConnectionImpl implements LegStarConnection {

    private static final String CLOSED_ERROR = "Connection closed";
    private static final String RESULT_SETS_NOT_SUPPORTED = "Result sets not supported";

    /** Logger. */
    private final Log log = LogFactory.getLog(getClass());

    private LegStarManagedConnection managedConnection;
    private boolean valid;

    public LegStarConnectionImpl(LegStarManagedConnection managedConnection) {

        super();
        this.managedConnection = managedConnection;
        valid = true;
    }

    public Interaction createInteraction() throws ResourceException {
        if (valid) {
            if (log.isDebugEnabled()) {
                log.debug("Creating new interaction");
            }
            return new LegStarInteractionImpl(this);
        } else {
            throw new ResourceException(CLOSED_ERROR);
        }
    }

    public void close() throws ResourceException {
        if (log.isDebugEnabled()) {
            log.debug("Closing connection");
        }
        if (valid) {
            managedConnection.close();
        }
    }

    public ResultSetInfo getResultSetInfo() throws ResourceException {
        throw new NotSupportedException(RESULT_SETS_NOT_SUPPORTED);
    }

    public void invalidate() {
        if (log.isDebugEnabled()) {
            log.debug("Invalidating connection");
        }
        managedConnection = null;
        valid = false;
    }

    public boolean isValid() {
        return valid;
    }

    public LocalTransaction getLocalTransaction() throws ResourceException {
        if (log.isDebugEnabled()) {
            log.debug("Creating new component-managed local transaction");
        }
        return new LegStarLocalTransactionImpl(managedConnection);
    }

    public void setManagedConnection(LegStarManagedConnection managedConnection) {
        this.managedConnection = managedConnection;

    }

    public LegStarManagedConnection getManagedConnection() {
        return managedConnection;
    }

    public ConnectionMetaData getMetaData() throws ResourceException {
        if (valid) {
            return createConnectionMetaData();
        } else {
            throw new ResourceException(CLOSED_ERROR);
        }
    }

    /**
     * create meta data for the specific transport.
     */
    public abstract ConnectionMetaData createConnectionMetaData();

}
